<?php

namespace App\Services\WxTemplatemsg;

use App\Facades\EasyWechat;
use App\Models\WxTemplatemsg;
use App\Models\WxTemplatemsgIndustry;
use App\Models\WxTemplatemsgLog;
use App\Services\SysConfig\SysConfigService;
use App\Services\WxCommon\WxError;
use Illuminate\Support\Facades\DB;

/**
 * 微信模板消息服务类
 * @package App\Services
 */
class WxTemplatemsgService extends \App\Services\WxCommon\WxBase
{
    const KEY_TEMPPLATE = 'template';
    const KEY_SERVICE_REMIND = 'service_remind';

    protected $keyList = [];

    /**
     * 构造函数
     */
    public function __construct($appid = '')
    {
        parent::__construct($appid);

        $this->keyList = [
            self::KEY_TEMPPLATE => '示例',
            self::KEY_SERVICE_REMIND => '服务评价提醒',
        ];
    }

    /**
     * 获取唯一标识名称
     * @param $key
     * @return mixed|string
     */
    public function getKeyName($key)
    {
        return isset($this->keyList[$key]) ? $this->keyList[$key] : '';
    }
    /**
     * 获取模板标识列表
     * @return array
     */
    public function getKeyList()
    {
        $list = [];
        if (!empty($this->keyList)) {
            foreach ($this->keyList as $k => $v) {
                $list[] = ['type' => $k, 'name' => $v];
            }
        }
        return $list;
    }

    /**
     * 获取行业配置分组列表，用来前端设置行业
     * @return array
     */
    public function getIndustryList()
    {
        $list = WxTemplatemsgIndustry::all()->toArray();
        $groupList = [];
        if ($list) {
            $topIndustry = [];
            foreach ($list as $v) {
                if (!in_array($v['main_industry'], $topIndustry)) {
                    $topIndustry[] = $v['main_industry'];
                }
                isset($groupList[$v['main_industry']]) || $groupList[$v['main_industry']] = [];
                $groupList[$v['main_industry']][] = ['id' => $v['industry_id'], 'name' => $v['sub_industry']];
            }
            if ($topIndustry) {
                $groupList[0] = [];
                foreach ($topIndustry as $industry) {
                    $groupList[0][] = ['id' => $industry, 'name' => $industry];
                }
            }
        }
        return $groupList;
    }

    /**
     * 获取当前服务号行业
     */
    public function getIndustry()
    {
        $configSer = new SysConfigService();
        $industrySet = $configSer->get(SysConfigService::WX_CARD_TEST_WHITE_LIST);
        if (empty($industrySet)) {
            $app = EasyWechat::officialAccount($this->appid);
            $apiRs = $app->template_message->getIndustry();
            //检查微信接口返回结果
            //WxError::checkApiResponse($apiRs);
            $industrySet = [
                'primary_industry_id' => 0,//主营行业ID
                'primary_industry_first_class' => '',//主营行业一级分类名
                'primary_industry_second_class' => '',//主营行业二级分类名
                'secondary_industry_id' => 0,//副营行业ID
                'secondary_industry_first_class' => '',//副营行业一级分类名
                'secondary_industry_second_class' => '',//副营行业一级分类名
            ];
            //主营行业
            if (!empty($apiRs['primary_industry']['first_class']) || !empty($apiRs['primary_industry']['second_class'])) {
                $find = WxTemplatemsgIndustry::where('sub_industry', $apiRs['primary_industry']['second_class'])
                    ->where('main_industry', $apiRs['primary_industry']['first_class'])
                    ->first();
                if ($find) {
                    $industrySet['primary_industry_id'] = $find['industry_id'];
                    $industrySet['primary_industry_first_class'] = $find['main_industry'];
                    $industrySet['primary_industry_second_class'] = $find['sub_industry'];
                }
            }
            //副营行业
            if (!empty($apiRs['secondary_industry']['first_class']) || !empty($apiRs['secondary_industry']['second_class'])) {
                $find = WxTemplatemsgIndustry::where('sub_industry', $apiRs['secondary_industry']['second_class'])
                    ->where('main_industry', $apiRs['secondary_industry']['first_class'])
                    ->first();
                if ($find) {
                    $industrySet['secondary_industry_id'] = $find['industry_id'];
                    $industrySet['secondary_industry_first_class'] = $find['main_industry'];
                    $industrySet['secondary_industry_second_class'] = $find['sub_industry'];
                }
            }
            $key = SysConfigService::WX_TEMPLATE_INDUSTRY . '_' . $this->appid;
            $configSer->set($key, $industrySet);
        }
        return $industrySet;
    }

    /**
     * 设置行业
     * @param $request
     * @return mixed
     * @throws \Exception
     */
    public function setIndustry($request)
    {
        if (empty($request->primary_industry_id)) {
            throw new \Exception('请选择主营行业');
        }
        if (empty($request->secondary_industry_id)) {
            throw new \Exception('请选择副营行业');
        }
        if ($request->primary_industry_id == $request->secondary_industry_id) {
            throw new \Exception('主营行业和副营行业不能一致');
        }
        $app = EasyWechat::officialAccount($this->appid);
        $apiRs = $app->template_message->setIndustry($request->primary_industry_id, $request->secondary_industry_id);
        //检查微信接口返回结果
        WxError::checkApiResponse($apiRs);
        $industrySet = [
            'primary_industry_id' => $request->primary_industry_id ?? 0,//主营行业ID
            'primary_industry_first_class' => $request->primary_industry_first_class ?? '',//主营行业一级分类名
            'primary_industry_second_class' => $request->primary_industry_second_class ?? '',//主营行业二级分类名
            'secondary_industry_id' => $request->secondary_industry_id ?? 0,//副营行业ID
            'secondary_industry_first_class' => $request->secondary_industry_first_class ?? '',//副营行业一级分类名
            'secondary_industry_second_class' => $request->secondary_industry_second_class ?? '',//副营行业一级分类名
        ];
        $configSer = new SysConfigService();
        $key = SysConfigService::WX_TEMPLATE_INDUSTRY . '_' . $this->appid;
        $configSer->set($key, $industrySet);
        //重新同步数据
        $this->sync();
        return true;
    }

    /**
     * 添加模型
     * @param $request
     * @return bool
     * @throws \Exception
     */
    public function add($request)
    {
        $template = new WxTemplatemsg;
        $template->appid = $this->appid;
        $template->template_key = $request->template_key ?? '';
        $template->template_id_short = $request->template_id_short ?? '';
        if (empty($template->template_key)) {
            throw new \Exception('请输入模板KEY');
        }
        if (empty($template->template_id_short)) {
            throw new \Exception('请输入模板库中的模板编号');
        }
        $app = EasyWechat::officialAccount($this->appid);
        $apiRs = $app->template_message->addTemplate($template->template_id_short);
        //检查微信接口返回结果
        WxError::checkApiResponse($apiRs);
        $template->template_id = $apiRs['template_id'] ?? '';
        if (empty($template->template_id)) {
            throw new \Exception('接口返回模板ID为空');
        }
        $template->content = '';
        $template->example = '';
        $rs = $template->save();
        //同步模板数据
        $this->sync();
        return $rs;
    }

    /**
     * 修改模板
     * @param $request
     * @return mixed
     * @throws \Exception
     */
    public function edit($request)
    {
        $id = $request->id ?? 0;
        $template = WxTemplatemsg::where('appid', $this->appid)->find($id);
        if (empty($template)) {
            throw new \Exception('您要编辑的模板无效');
        }
        $template->template_key = $request->template_key ?? '';
        if (empty($template->template_key)) {
            throw new \Exception('请输入模板KEY');
        }
        return $template->save();
    }

    /**
     * 删除模板
     * @param $id
     * @return bool
     * @throws \Exception
     */
    public function del($id)
    {
        $find = WxTemplatemsg::where('appid', $this->appid)->find($id);
        if (empty($find)) {
            throw new \Exception('模板不存在');
        }
        $app = EasyWechat::officialAccount($this->appid);
        $apiRs = $app->template_message->deletePrivateTemplate($find->template_id);
        //检查微信接口返回结果
        WxError::checkApiResponse($apiRs);
        return $find->delete();
    }

    /**
     * 同步线上模板
     * @return bool
     * @throws \Exception
     */
    public function sync()
    {
        $app = EasyWechat::officialAccount($this->appid);
        $apiRs = $app->template_message->getPrivateTemplates();
        //检查微信接口返回结果
        WxError::checkApiResponse($apiRs);
        Db::beginTransaction();
        try {
            WxTemplatemsg::where('appid', $this->appid)->where('id', '>', 0)->delete();
            if (!empty($apiRs['template_list'])) {
                foreach ($apiRs['template_list'] as $template) {
                    WxTemplatemsg::withTrashed()->updateOrCreate(
                        ['appid' => $this->appid,'template_id' => $template['template_id']],
                        [
                            'title' => $template['title'] ?? '',
                            'primary_industry' => $template['primary_industry'] ?? '',
                            'deputy_industry' => $template['deputy_industry'] ?? '',
                            'content' => $template['content'] ?? '',
                            'example' => $template['example'] ?? '',
                        ]
                    )->restore();
                }
            }
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollBack();
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 模板消息发送
     * @param $templateKey
     * @param $data
     * @return bool
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     */
    public function send($templateKey, $data)
    {
        $find = WxTemplatemsg::where('appid', $this->appid)->where('template_key', $templateKey)->first();
        if (empty($find)) {
            throw new \Exception('请指定有效的模板标识');
        }
        $data['template_id'] = $find->template_id ?? '';
        if (empty($data['template_id'])) {
            throw new \Exception('模板ID不能为空');
        }
        if (empty($data['touser'])) {
            throw new \Exception('请输入接收者openId');
        }
        $app = EasyWechat::officialAccount($this->appid);
        $apiRs = $app->template_message->send($data);
        //检查微信接口返回结果
        $errcode = 0;
        $errmsg = '';
        try {
            WxError::checkApiResponse($apiRs);
        } catch (\Exception $e) {
            $errcode = 1;
            $errmsg = $e->getMessage();
        }
        //写日志
        return WxTemplatemsgLog::create([
            'appid' => $this->appid,
            'template_key' => $find['template_key'],
            'msgid' => !empty($apiRs['msgid']) ? $apiRs['msgid'] : '0',
            'touser' => $data['touser'],
            'template_id' => $data['template_id'],
            'content' => $data,
            'errcode' => $errcode,
            'errmsg' => $errmsg,
        ]);
    }

    /**
     * 模板消息发送结果处理
     * @param $eventData
     * @return mixed
     * @throws \Exception
     */
    public function sendResultHandle($eventData)
    {
        $msgID = !empty($eventData['MsgID']) ? $eventData['MsgID'] : '';
        if (empty($eventData['MsgID'])) {
            throw new \Exception('消息ID不能为空');
        }
        $findLog = WxTemplatemsgLog::where('appid', $this->appid)->where('msgid', $msgID)->first();
        if (empty($findLog)){
            return false;
        }
        $findLog->send_status = $eventData['Status'] ?? '';
        return $findLog->save();
    }
}